﻿@implements IDisposable
@using Podcast.Components.ListenTogether
@using CommunityToolkit.Mvvm.Messaging
@using Microsoft.NetConf2021.Maui.Messaging
@using static Podcast.Components.ListenTogether.ListenTogether
@inject ThemeInterop ThemeInterop
@inject PlayerService PlayerService

<ListenTogether @ref="listenTogetherRef"
				CanCreateRoom="@canCreateRoom"
				EpisodeId="@episodeId"
				RoomCode="@roomCode"
				OnJoinRoom="@JoinRoom"
				OnCreateRoom="@CreateRoom"
				OnRoomCreated="@UpdateRoomPlayerState"
				OnLeaveRoom="@LeaveRoom"
				OnPlayerStateChange="@UpdatePlayer" />

@code {
    private ListenTogether? listenTogetherRef;
    private Guid? episodeId;
    private string? roomCode;
    private bool canCreateRoom = false;

    protected override void OnInitialized()
    {
        WeakReferenceMessenger.Default
            .Register<ListenTogetherComponent, ChangeThemeNotification>(
                this,
                async (r, n) =>
                {
                    await UpdateWebThemeAsync();
                });

        WeakReferenceMessenger.Default
            .Register<ListenTogetherComponent, LeaveRoomNotification>(
                this,
                async (r, n) =>
                {
                    LeaveRoom();
                    await InvokeAsync(StateHasChanged);
                });

        canCreateRoom = PlayerService.CurrentEpisode != null;
        PlayerService.NewEpisodeAdded += NewEpisodeAddedToPlayer;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await UpdateWebThemeAsync();
        }
    }

    public void Dispose()
    {
        PlayerService.IsPlayingChanged -= IsLocalPlayingChanged;
        PlayerService.NewEpisodeAdded -= NewEpisodeAddedToPlayer;

        WeakReferenceMessenger.Default.Unregister<ChangeThemeNotification>(this);
        WeakReferenceMessenger.Default.Unregister<LeaveRoomNotification>(this);
    }

    private void JoinRoom(string roomCode)
    {
        this.roomCode = roomCode;
        PlayerService.IsPlayingChanged += IsLocalPlayingChanged;
    }

    private void LeaveRoom()
    {
        PlayerService.IsPlayingChanged -= IsLocalPlayingChanged;
        roomCode = null;
    }

    private void CreateRoom()
    {
        episodeId = PlayerService.CurrentEpisode?.Id;
    }

    private async void UpdatePlayer(RoomPlayerState playerState)
    {
        PlayerService.IsPlayingChanged -= IsLocalPlayingChanged;

        var episode = new Episode(playerState);
        var show = new Show(playerState);

        await PlayerService.PlayAsync(episode, show, playerState.IsPlaying, playerState.Progress.TotalSeconds);

        PlayerService.IsPlayingChanged += IsLocalPlayingChanged;
    }

    private async Task UpdateRoomPlayerState()
    {
        if (listenTogetherRef != null)
        {
            double currentTime = PlayerService?.CurrentPosition ?? 0;
            bool isPlaying = PlayerService?.IsPlaying ?? false;

            await listenTogetherRef.UpdateRoomPlayerState((long)currentTime, isPlaying);
        }
    }

    private async Task UpdateWebThemeAsync()
    {
        var darkModeIsActive = Settings.Theme == AppTheme.Dark;
        await ThemeInterop.SetThemeAsync(darkModeIsActive ? Theme.Dark : Theme.Light);

    }

    private async void IsLocalPlayingChanged(object sender, EventArgs e)
    {
        await UpdateRoomPlayerState();
    }

    private async void NewEpisodeAddedToPlayer(object sender, EventArgs e)
    {
        canCreateRoom = PlayerService.CurrentEpisode != null;
        await InvokeAsync(StateHasChanged);
    }
}
